from main.models import Excursion, Image, Outcrop, Excursion_Members, Outcrop_Collection, Tag
from modelSerializers import ExcursionSerializer, OutcropSerializer
from django.contrib.auth.models import User
from django.shortcuts import redirect
from rest_framework import generics
from rest_framework.permissions import IsAuthenticated
from rest_framework.authentication import SessionAuthentication, TokenAuthentication
from rest_framework.decorators import api_view, authentication_classes, permission_classes
from rest_framework.response import Response
from rest_framework.reverse import reverse
from rest_framework import status

"""
Loads the main api page.
@precondition: must be a HTTP GET request.
""" 
@api_view(['GET',])
def api_root(request):
    return Response({
        'excursion': reverse('/api/excursion/', request=request, format=format),
        'outcrop': reverse('/api/outcrop/', request=request, format=format),
        'tag': reverse('/api/tag/', request=request, format=format),
        })

"""
View to allow a file and its associated data to be uploaded.
@precondition: must be a HTTP POST request.
""" 
@api_view(['POST'])
@authentication_classes((SessionAuthentication, TokenAuthentication))
@permission_classes((IsAuthenticated,))
def upload_file(request):
    if request.method == 'POST':
        user = User.objects.get(username=request.user)
        if (user is not None) and (not user.is_anonymous()):
            excursion = Excursion.objects.get(pk=request.DATA['excursion_id'])
            if int(request.DATA['outcrop_id']) == -1:
                outcrop = None
            else:
                try:
                    outcrop = Outcrop.objects.get(pk=request.DATA['outcrop_id'])
                except Outcrop.DoesNotExist:
                    outcrop = None
            if int(request.DATA['geoData']) == 1:    #has geo data
                instance = Image(owner=user, excursion=excursion, outcrop=outcrop, name=request.DATA['name'], image=request.FILES['image'], public=excursion.public, notes=request.DATA['notes'],
                                 altitude=request.DATA['altitude'], longitude=request.DATA['longitude'], latitude=request.DATA['latitude'], heading=None,
                                 hAccuracy=request.DATA['hAccuracy'], vAccuracy=request.DATA['vAccuracy'])
            else:
                instance = Image(owner=user, excursion=excursion, outcrop=outcrop, name=request.DATA['name'], image=request.FILES['image'], public=excursion.public, notes=request.DATA['notes'],
                                 altitude=None, longitude=None, latitude=None, heading=None,
                                 hAccuracy=None, vAccuracy=None)
            instance.save()
            
            tags = str(request.DATA['tags']).split(',')
            tag_instance = None
            for tag in tags:
                if (not (len(tag) > 128)) and (tag is not None) and (tag is not "") and (tag is not " "):
                    tag_instance = Tag(image=instance, tag=str(tag))
                    tag_instance.save()
            
            return Response(status=status.HTTP_201_CREATED)
        else:
            return Response(status=status.HTTP_401_UNAUTHORIZED)
    else:
        return redirect('/image/')

"""
View which returns all of the excursions a user is a member of.
@precondition: the user must be authenticated.
""" 
class ExcursionList(generics.ListAPIView):
    authentication_classes = (SessionAuthentication, TokenAuthentication)
    permission_classes = (IsAuthenticated,)
    model = Excursion
    serializer_class = ExcursionSerializer
    
    def get_queryset(self):
        """
        This view should return a list of all the excursions
        for the currently authenticated user.
        """
        user = self.request.user
        excursions = Excursion.objects.filter(pk__in=(Excursion_Members.objects.filter(user=user).values('excursion__pk')))
        return excursions

class ExcursionInstance(generics.RetrieveUpdateDestroyAPIView):
    """
    Retrieve, update or delete an Excursion instance.
    """
    authentication_classes = (SessionAuthentication, TokenAuthentication)
    permission_classes = (IsAuthenticated,)
    model = Excursion
    serializer_class = ExcursionSerializer
    
    def pre_save(self, obj):
        obj.owner = self.request.user

"""
Returns all outcrops for a given excursion id, the excursion id must be
passed as a get variable (ex_id) in the url.
"""
class OutcropList(generics.ListCreateAPIView):
    """
    List all Excursion, or create a new information instance
    """
    authentication_classes = (SessionAuthentication, TokenAuthentication)
    permission_classes = (IsAuthenticated,)
    model = Outcrop
    serializer_class = OutcropSerializer
    
    def get_queryset(self):
        """
        This view should return a list of all the oucrops
        for the excursion with a given id.
        """
        excursion = Excursion.objects.get(pk=self.request.QUERY_PARAMS['ex_id'])
        outcrops = Outcrop.objects.filter(pk__in=Outcrop_Collection.objects.filter(excursion=excursion).values('outcrop__pk'))
        return outcrops